<html>
    <head>
        <title>ABP 虚拟文件系统</title>
    </head>
    <body>
        <script>
            // 虚拟文件系统

                    /*
                        虚拟文件系统可以物理上(磁盘上)不存在的文件。
                        它主要用于将 (js、css、image...) 文件嵌入到程序集中，并在运行时像物理文件一样使用它们。
                    */

                    /*
                        一、安装
                                大多数时候，你不需要手动安装此软件包，因为它预装了应用程序启动模板。
                                
                                "Volo. Abp.VirtualFileSystem:" 是虚拟文件系统的主包。

                                1、使用ABP CLI将此包添加到你的项目中：

                                        在要添加Volo.Abp.VirtualFileSystem包的.csproj文件目录中打开命令行（终端）。

                                        运行abp add-package Volo.Abp.VirtualFileSystem命令。

                                2、手动安装
                                        如果你想手动执行此操作，请将Volo. Abp.VirtualFileSystemNuGet包安装到你的项目中，
                                        并将[DependsOn(typeof(AbpVirtualFileSystemModule))]添加到项目内的ABP模块类中
                    */

                    /*
                        二、使用嵌入式文件

                                应首先将文件标记为"嵌入式资源"以将文件嵌入到程序集中.

                                1、嵌入文件
                                        
                                        ①、最简单的方式： 最简单的方法是从 "解决方案资源管理器"中选择文件，并从"属性窗口" 将 "构建操作" 设置为"嵌入式资源"。

                                        ②、编辑项目文件 .csproj：
                                                如果要添加多个文件，直接在 visual studio 中操作不方便，可以直接编辑 .csproj 文件

                                                    <ItemGroup>
                                                        <EmbeddedResource Include="MyResources\**\*.*" />
                                                        <Content Remove="MyResources\**\*.*" />
                                                    </ItemGroup>
                                                此配置递归地添加项目MyResources文件夹下的所有文件（包括你将来将添加的文件）。

                                                如果文件名包含一些特殊字符，则在项目/程序集中嵌入文件可能会导致问题。
                                                为了克服这个限制：
                                                  
                                                    将Microsoft. Exents.FileProviders.EmbeddedNuGet包添加到包含嵌入式资源的项目中。

                                                    将<GenerateEmbeddedFilesManifest（生成嵌入式文件清单）>true</GenerateEmbeddedFilesManifest>添加到.csproj文件的<PropertyGroup>...</PropertyGroup>部分。
                    
                    
                               2、配置虚拟文件系统  AbpVirtualFileSystemOptions
                                        （将嵌入式文件注册到虚拟文件系统）
                                        使用 AbpVirtualFileSystemOptions 选项类将 "嵌入式文件" 注册到模块的 ConfigureServices 方法中》

                                        eg： 将嵌入式文件添加到虚拟文件系统:

                                                Configure<AbpVirtualFileSystemOptions>(options=>{
                                                    options.FileSets.AddEmbedded<MyModule>();     // 将给定类型所在程序集中的嵌入式文件添加到虚拟文件系统。 
                                                });

                                            AddEmbedded()方法可以有两个参数：
                                                  ①、baseNamespace：  
                                                            当你没有配置上面解释的GenerateEmbeddedFilesManifest（生成嵌入式文件清单）步骤并且你的根命名空间不为空时才需要。
                                                            在这种情况下，请在此处设置你的根命名空间。 

                                                  ②、baseFolder
                                                            如果你不想公开项目中的所有嵌入式文件，但是只想公开特定文件夹(和子文件夹/文件)，
                                                            那么你可以相对于你的项目根文件夹设置基本文件夹。
                                                
                                                eg:   在项目中的 MyResources 文件夹在添加文件
                                                            Configure<AbpVirtualFileSystemOptions>(options =>
                                                            {
                                                                options.FileSets.AddEmbedded<MyModule>(
                                                                    baseNamespace: "Acme.BookStore", // 设置根命名空间
                                                                    baseFolder: "/MyResources"  // 设置根文件夹(项目中的文件夹路径)
                                                                );
                                                            });

                                                            本例子假设：
                                                                 你的项目根（默认）命名空间是Acme.BookStore。
                                                                 你的项目有一个文件夹，名为MyResources
                                                                 你只想将MyResources文件夹添加到虚拟文件系统。  
                    */

                    /*
                          三、IVirtualFileProvider 虚拟文件提供程序接口 （如何使用虚拟文件）
                          
                                   将文件嵌入到程序集中，并将其注册到"虚拟文件系统"后， 
                                   IVirtualFileProvider接口可用于获取文件或目录内容：

                                            public class MyService: ITransientDependency
                                            {
                                                private readonly IVirtualFileProvider _virtualFileProvider;

                                                // 注入虚拟文件提供程序服务
                                                public MyService(IVirtualFileProvider virtualFileProvider)
                                                {
                                                    _virtualFileProvider = virtualFileProvider;
                                                }

                                                public void Test()
                                                {
                                                    // 获取虚拟文件系统中的单个文件
                                                    var file =_virtualFileProvider.GetFileInfo("/MyResources/js/test.js");

                                                    var fileContent = file.ReadAllText();  // 获取文件内容

                                                    // 获取文件夹中子目录/文件

                                                    var directoryContents =_virtualFileProvider.GetDirectoryContents("/MyResources/js");
                                                }
                                            }
                    */

                    /*
                        四、asp.net core 集成

                                虚拟文件系统很好地集成到ASP.NET core：

                                    虚拟文件可以像Web应用程序中的静态文件一样使用。

                                    js、css、图像文件和所有其他Web内容类型都可以嵌入到程序集中并像物理文件一样使用

                                    应用程序（或另一个模块）可以覆盖模块的虚拟文件，就像将具有相同名称和扩展名的文件放入虚拟文件的同一文件夹一样。


                                ★、静态虚拟文件夹
                                        默认情况下，ASP.NETCore只允许wwwroot文件夹包含客户端使用的静态文件。
                                        当你使用虚拟文件系统时，以下文件夹也可以包含静态文件：

                                            ①、Pages
                                            ②、Views
                                            ③、Components
                                            ④、Themes
                                        这允许在你的.cshtml文件附近添加.js、.css…文件，这些文件更易于开发和维护你的项目。
                    */

                    /*
                        五、在开发过程中处理嵌入式文件
                                将文件嵌入到程序集中并能够通过引用程序集（或添加NuGet包）从另一个项目中使用它对于创建可重用模块非常宝贵。
                                然而，这使得开发模块本身有点困难。

                                假设你正在开发一个包含嵌入式JavaScript文件的模块。
                                每当你更改此文件时，你必须重新编译项目，重新启动应用程序并刷新浏览器页面以进行更改。显然，这非常耗时且乏味。

                                需要的是应用程序能够在开发时直接使用物理文件，并且浏览器刷新反映JavaScript文件中所做的任何更改。
                                ReplaceEmbeddedByPhysical方法使这一切成为可能。

                                下面的示例显示了一个依赖于包含嵌入式文件的模块（MyModule）的应用程序。
                                应用程序可以在开发时访问模块的源代码。

                                    [DependsOn(typeof(MyModule))]
                                    public class MyWebAppModule : AbpModule
                                    {
                                        public override void ConfigureServices(ServiceConfigurationContext context)
                                        {
                                            var hostingEnvironment = context.Services.GetHostingEnvironment();

                                            if (hostingEnvironment.IsDevelopment()) // 在开发环境中
                                            {
                                                Configure<AbpVirtualFileSystemOptions>(options =>
                                                {
                                                    // 开发时，使用物理文件替换嵌入式文件
                                                    options.FileSets.ReplaceEmbeddedByPhysical<MyModule>(
                                                        Path.Combine( // 指定物理文件路径
                                                            hostingEnvironment.ContentRootPath,
                                                            string.Format(
                                                                "..{0}MyModuleProject",
                                                                Path.DirectorySeparatorChar
                                                            )
                                                        )
                                                    );
                                                });
                                            }
                                        }
                                    }
                                上面的代码假定MyWebAppModule和MyModule是Visual Studio解决方案中的两个不同项目，并且MyWebAppModule依赖于MyModule。
                                应用程序启动模板已经对本地化文件使用了这种技术。因此，当你更改本地化文件时，它会自动检测到更改。
                    */

                    /*
                        六、替换/覆盖虚拟文件

                                Virtual File System在运行时创建一个统一的文件系统，其中实际文件在开发时分布到不同的模块中。
                                如果两个模块将文件添加到同一虚拟路径（如my-path/my-file.css），则稍后添加的模块会覆盖/替换前一个模块（模块依赖项顺序决定了添加文件的顺序）。
                                此功能允许你的应用程序覆盖/替换定义为应用程序使用的模块的任何虚拟文件。这是ABP的基本可扩展性功能之一。
                                因此，如果你需要替换模块的文件，只需在模块/应用程序中完全相同的路径中创建文件。

                                
                                ★、物理文件
                                       物理文件总是覆盖虚拟文件。
                                       意味着如果你将文件放在/wwwroot/my-folder/my-file.css下，它将覆盖虚拟文件系统同一位置的文件。
                                       因此，你需要知道模块中定义的文件路径才能覆盖它们。
                                        
                    */
        </script>
    </body>
</html>